package com.jf.car.util;



import lombok.extern.java.Log;

import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;

@Log
public class BaseDao {
	/*初始化数据库配置信息*/
	private static final String DRIVER;
	private static final String URL;
	private static final String USERNAME;
	private static final String PASSWORD;

	static {
		ResourceBundle rb = ResourceBundle.getBundle("jdbc");
		DRIVER = rb.getString("jdbc.driver");
		URL = rb.getString("jdbc.url");
		USERNAME = rb.getString("jdbc.username");
		PASSWORD = rb.getString("jdbc.password");
	}

	/**
	 * 声明数据库连接类
	 */
	private static Connection conn = null;
	/**
	 * 声明SQL执行器
	 */
	private static PreparedStatement pstm =null;
	/**
	 * 声明结果集
	 */
	private static ResultSet rs = null;

	/**
	 * 通用增删改
	 * @param sql	要执行的SQL
	 * @param objs	SQL占位符组成的数组
	 * @return		受影响行数
	 */
	public static int baseUpdate(String sql,Object ...objs) {
		formatSql(sql, objs);
		try {
			// 执行并返回结果
			return pstm.executeUpdate();
		} catch (SQLException e) {
			log.info(e.getMessage());
		}finally {
			closeAll();
		}
		return 0;
	}
	/**
	 * 通用增删改
	 */
	public static int baseUpdate(String sql,List<Object> list) {
		if(list != null&& !list.isEmpty()) {
			Object[] objs = list.toArray();
			return baseUpdate(sql,objs);
		}
		return baseUpdate(sql);
	}
	/**
	 * 通用查询
	 * @param tClass	结果集泛型类型
	 * @param sql		执行的SQL
	 * @param objs		参数列表
	 */
	public static <T> List<T> baseQuery(Class<T> tClass,String sql,Object ...objs) {
		// 初始化最终结果
		List<T> list = new ArrayList<>();
		formatSql(sql, objs);
		try {
			// 执行SQL获取结果集
			rs = pstm.executeQuery();
			// 获取结果集的元数据
			ResultSetMetaData rsmd = pstm.getMetaData();
			// 获取列的总数
			int columnCount = rsmd.getColumnCount();
			// 获取类中的所有属性
			Field[] fs = tClass.getDeclaredFields();
			// 遍历结果集
			while(rs.next()) {
				// 获取实体类
				T t = tClass.newInstance();
				// 遍历属性
				for(Field f : fs) {
					// 获取属性名
					String fieldName = f.getName();
					// 遍历列名
					for(int i=1;i<=columnCount;i++) {
						// 获取列名
						String labelName = rsmd.getColumnLabel(i);
						// 获取列对应的值
						Object value = rs.getObject(labelName);
						// 判断列名是否包含下划线
						if(labelName.contains("_")) {
							// 拆分字符串
							String[] lns = labelName.split("_");
							// 获取第一个单词
							String word = lns[0];
							// 便利数组处理第二个开始的单词
							for(int j=1;j<lns.length;j++) {
								String w = lns[j].substring(0,1).toUpperCase();
								String d = lns[j].substring(1);
								word += (w+d);
							}
							labelName = word;
						}
						// 验证属性名和列名是否一致
						if(fieldName.equals(labelName)) {
							// 给对应的属性赋值到实体类中
							f.setAccessible(true);
							f.set(t, value);
						}
					}
				}
				list.add(t);
			}
		} catch (SQLException | InstantiationException | IllegalAccessException e) {
			log.info(e.getMessage());
		} finally {
			closeAll();
		}
		return list;
	}

	/**
	 * 通用查询
	 * @param tClass	结果集泛型类型
	 * @param sql		执行的SQL
	 * @param list		参数列表
     */
	public static <T> List<T> baseQuery(Class<T> tClass,String sql,List<Object> list){
		return baseQuery(tClass, sql,list.toArray());
	}
	/**
	 * 通用查询
	 * @param tClass	结果集泛型类型
	 * @param sql		执行的SQL
	 * @param objs		参数列表
     */
	public static <T> T baseQueryBean(Class<T> tClass,String sql,Object ...objs) {
		List<T> list = baseQuery(tClass, sql, objs);
		if(list.size() == 1) {
			return list.get(0);
		}
		if(list.isEmpty()) {
			return null;
		}
		throw new RuntimeException("结果不是单个");
	}
	/**
	 * 通用查询
	 * @param tClass	结果集泛型类型
	 * @param sql		执行的SQL
	 * @param list		参数列表
     */
	public static <T> T baseQueryBean(Class<T> tClass,String sql,List<Object> list) {
		return baseQueryBean(tClass, sql, list.toArray());
	}
	/**
	 * 通用聚合查询
     */
	public static int baseQueryCount(String sql,Object ...objs) {
		formatSql(sql, objs);
		try {
			rs=pstm.executeQuery();
			if(rs.next()) {
				return rs.getInt(1);
			}
		} catch (SQLException e) {
			log.info(e.getMessage());
		}finally {
			closeAll();
		}
		return 0;
	}
	/**
	 * 通用聚合查询
     */
	public static int baseQueryCount(String sql,List<Object> list) {
		return baseQueryCount(sql, list.toArray());
	}

	/**
	 * 通用批量增删改(手动事务)
	 */
	public static int baseBatch(String sql,int len,Object ...objs){
        try {
			formatSql(sql,objs);
			/*设置事务手动提交*/
			conn.setAutoCommit(false);
			int result = pstm.executeUpdate();
			if(result == len){
				/*预期结果和实际结果一致则提交事务*/
				conn.commit();
			}else{
				/*否则回滚事务，会让所有已成功数据还原*/
				conn.rollback();
			}
			return result;
        } catch (SQLException e) {
            try {
                conn.rollback();
            } catch (SQLException ex) {
                throw new RuntimeException(ex);
            }
            throw new RuntimeException(e);
        }
    }

	public static int baseBatch(String sql,int len,List<Object> list){
		return baseBatch(sql,len,list.toArray());
	}
	/**
	 * 获取数据库连接
	 */
	private static void getConnection() {
		try {
			// 加载驱动
			Class.forName(DRIVER);
			// 获取连接
			conn = DriverManager.getConnection(URL,USERNAME,PASSWORD);
		} catch (ClassNotFoundException | SQLException e) {
			log.info(e.getMessage());
		}
    }

	/**
	 * 封装占位符内容
	 */
	private static void formatSql(String sql,Object[] objs) {
		getConnection();
		try {
			pstm=conn.prepareStatement(sql);
			for(int i=0;i<objs.length;i++) {
				pstm.setObject(i+1, objs[i]);
			}
			System.out.println(pstm);
		} catch (SQLException e) {
			log.info(e.getMessage());

		}
	}

	/**
	 * 关闭连接
	 */
	private static void closeAll() {
		try {
			if(rs != null) {
				rs.close();
			}
			if(pstm != null) {
				pstm.close();
			}
			if(conn != null) {
				conn.close();
			}
		}catch (SQLException e) {
			log.info(e.getMessage());
		}
	}
}
